
local alien = require 'alien'
local alienex = require 'alienex'
local config = require 'config'


module(...)


local lib = alien.load(config.libpng_path)

color = alien.defstruct{
  {"red", "char"};
  {"green", "char"};
  {"blue", "char"};
}

color_16 = alien.defstruct{
  {"index", "char"};
  {"red", "ushort"};
  {"green", "ushort"};
  {"blue", "ushort"};
  {"gray", "ushort"};
}

color_8 = alien.defstruct{
  {"red", "char"};
  {"green", "char"};
  {"blue", "char"};
  {"gray", "char"};
  {"alpha", "char"};
}

--[[
SIZE_T ??

text = alien.defstruct{
  {"compression", "int"};
  {"key", "pointer"};
  {"text", "pointer"};
  {"text_length", assert(size_t)};
}
--]]

LIBPNG_VER_STRING = "1.2.34"

TEXT_COMPRESSION_NONE_WR = -3
TEXT_COMPRESSION_zTXt_WR = -2
TEXT_COMPRESSION_NONE = -1
TEXT_COMPRESSION_zTXt = 0

time = alien.defstruct{
  {"year", "ushort"};
  {"month", "char"};
  {"day", "char"};
  {"hour", "char"};
  {"minute", "char"};
  {"second", "char"};
}

info = alien.defstruct{
  -- the following are necessary for every PNG file
  {"width", "uint"};
  {"height", "uint"};
  {"valid", "uint"};
  {"rowbytes", "uint"};
  {"palette", "pointer" --[[png_colorp]]};
  {"num_palette", "ushort"};
  {"num_trans", "ushort"};
  {"bit_depth", "char"};
  {"color_type", "char"};
  {"compression_type", "char"};
  {"filter_type", "char"};
  {"interlace_type", "char"};

  -- The following is informational only on read, and not used on writes.
  {"channels", "char"};
  {"pixel_depth", "char"};
  {"spare_byte", "char"};
  {"signature_1", "char"};
  {"signature_2", "char"};
  {"signature_3", "char"};
  {"signature_4", "char"};
  {"signature_5", "char"};
  {"signature_6", "char"};
  {"signature_7", "char"};
  {"signature_8", "char"};

  --[=[
   /* The rest of the data is optional.  If you are reading, check the
    * valid field to see if the information in these are valid.  If you
    * are writing, set the valid field to those chunks you want written,
    * and initialize the appropriate fields below.
    */

#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED) || \
    defined(PNG_READ_GAMMA_SUPPORTED)
   /* The gAMA chunk describes the gamma characteristics of the system
    * on which the image was created, normally in the range [1.0, 2.5].
    * Data is valid if (valid & PNG_INFO_gAMA) is non-zero.
    */
   float gamma; /* gamma value of image, if (valid & PNG_INFO_gAMA) */
#endif /* PNG_READ_gAMA_SUPPORTED || PNG_WRITE_gAMA_SUPPORTED */

#if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
    /* GR-P, 0.96a */
    /* Data valid if (valid & PNG_INFO_sRGB) non-zero. */
   png_byte srgb_intent; /* sRGB rendering intent [0, 1, 2, or 3] */
#endif /* PNG_READ_sRGB_SUPPORTED || PNG_WRITE_sRGB_SUPPORTED */

#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \
    defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
   /* The tEXt and zTXt chunks contain human-readable textual data in
    * uncompressed and compressed forms, respectively.  The data in "text"
    * is an array of pointers to uncompressed, null-terminated C strings.
    * Each chunk has a keyword that describes the textual data contained
    * in that chunk.  Keywords are not required to be unique, and the text
    * string may be empty.  Any number of text chunks may be in an image.
    */
   int num_text; /* number of comments read/to write */
   int max_text; /* current size of text array */
   "pointer" --[[png_textp text]]; /* array of comments read/to write */
#endif /* PNG_READ_OR_WRITE_tEXt_OR_zTXt_SUPPORTED */
#if defined(PNG_READ_tIME_SUPPORTED) || defined(PNG_WRITE_tIME_SUPPORTED)
   /* The tIME chunk holds the last time the displayed image data was
    * modified.  See the png_time struct for the contents of this struct.
    */
   png_time mod_time;
#endif /* PNG_READ_tIME_SUPPORTED || PNG_WRITE_tIME_SUPPORTED */
#if defined(PNG_READ_sBIT_SUPPORTED) || defined(PNG_WRITE_sBIT_SUPPORTED)
   /* The sBIT chunk specifies the number of significant high-order bits
    * in the pixel data.  Values are in the range [1, bit_depth], and are
    * only specified for the channels in the pixel data.  The contents of
    * the low-order bits is not specified.  Data is valid if
    * (valid & PNG_INFO_sBIT) is non-zero.
    */
   png_color_8 sig_bit; /* significant bits in color channels */
#endif /* PNG_READ_sBIT_SUPPORTED || PNG_WRITE_sBIT_SUPPORTED */
#if defined(PNG_READ_tRNS_SUPPORTED) || defined(PNG_WRITE_tRNS_SUPPORTED) || \
    defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
   /* The tRNS chunk supplies transparency data for paletted images and
    * other image types that don't need a full alpha channel.  There are
    * "num_trans" transparency values for a paletted image, stored in the
    * same order as the palette colors, starting from index 0.  Values
    * for the data are in the range [0, 255], ranging from fully transparent
    * to fully opaque, respectively.  For non-paletted images, there is a
    * single color specified that should be treated as fully transparent.
    * Data is valid if (valid & PNG_INFO_tRNS) is non-zero.
    */
   "pointer" --[[png_bytep trans]]; /* transparent values for paletted image */
   png_color_16 trans_values; /* transparent color for non-palette image */
#endif /* PNG_READ_tRNS_SUPPORTED || PNG_WRITE_tRNS_SUPPORTED */
#if defined(PNG_READ_bKGD_SUPPORTED) || defined(PNG_WRITE_bKGD_SUPPORTED) || \
    defined(PNG_READ_BACKGROUND_SUPPORTED)
   /* The bKGD chunk gives the suggested image background color if the
    * display program does not have its own background color and the image
    * is needs to composited onto a background before display.  The colors
    * in "background" are normally in the same color space/depth as the
    * pixel data.  Data is valid if (valid & PNG_INFO_bKGD) is non-zero.
    */
   png_color_16 background;
#endif /* PNG_READ_bKGD_SUPPORTED || PNG_WRITE_bKGD_SUPPORTED */
#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
   /* The oFFs chunk gives the offset in "offset_unit_type" units rightwards
    * and downwards from the top-left corner of the display, page, or other
    * application-specific co-ordinate space.  See the PNG_OFFSET_ defines
    * below for the unit types.  Valid if (valid & PNG_INFO_oFFs) non-zero.
    */
   "uint" --[[x_offset]]; /* x offset on page */
   "uint" --[[y_offset]]; /* y offset on page */
   png_byte offset_unit_type; /* offset units type */
#endif /* PNG_READ_oFFs_SUPPORTED || PNG_WRITE_oFFs_SUPPORTED */
#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
   /* The pHYs chunk gives the physical pixel density of the image for
    * display or printing in "phys_unit_type" units (see PNG_RESOLUTION_
    * defines below).  Data is valid if (valid & PNG_INFO_pHYs) is non-zero.
    */
   "uint" --[[x_pixels_per_unit]]; /* horizontal pixel density */
   "uint" --[[y_pixels_per_unit]]; /* vertical pixel density */
   png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */
#endif /* PNG_READ_pHYs_SUPPORTED || PNG_WRITE_pHYs_SUPPORTED */
#if defined(PNG_READ_hIST_SUPPORTED) || defined(PNG_WRITE_hIST_SUPPORTED)
   /* The hIST chunk contains the relative frequency or importance of the
    * various palette entries, so that a viewer can intelligently select a
    * reduced-color palette, if required.  Data is an array of "num_palette"
    * values in the range [0,65535]. Data valid if (valid & PNG_INFO_hIST)
    * is non-zero.
    */
   "pointer" --[[png_uint_16p hist]];
#endif /* PNG_READ_hIST_SUPPORTED || PNG_WRITE_hIST_SUPPORTED */
#if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED)
   /* The cHRM chunk describes the CIE color characteristics of the monitor
    * on which the PNG was created.  This data allows the viewer to do gamut
    * mapping of the input image to ensure that the viewer sees the same
    * colors in the image as the creator.  Values are in the range
    * [0.0, 0.8].  Data valid if (valid & PNG_INFO_cHRM) non-zero.
    */
   float x_white;
   float y_white;
   float x_red;
   float y_red;
   float x_green;
   float y_green;
   float x_blue;
   float y_blue;
#endif /* PNG_READ_cHRM_SUPPORTED || PNG_WRITE_cHRM_SUPPORTED */
#if defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED)
   /* The pCAL chunk describes a transformation between the stored pixel
    * values and original physcical data values used to create the image.
    * The integer range [0, 2^bit_depth - 1] maps to the floating-point
    * range given by [pcal_X0, pcal_X1], and are further transformed by a
    * (possibly non-linear) transformation function given by "pcal_type"
    * and "pcal_params" into "pcal_units".  Please see the PNG_EQUATION_
    * defines below, and the PNG-Group's Scientific Visualization extension
    * chunks document png-scivis-19970203 for a complete description of the
    * transformations and how they should be implemented, as well as the
    * png-extensions document for a description of the ASCII parameter
    * strings.  Data values are valid if (valid & PNG_INFO_pCAL) non-zero.
    */
   "pointer" --[[png_charp pcal_purpose]];  /* pCAL chunk description string */
   png_int_32 pcal_X0;      /* minimum value */
   png_int_32 pcal_X1;      /* maximum value */
   "pointer" --[[png_charp pcal_units]];    /* Latin-1 string giving physical units */
   "pointer" --[[png_charpp pcal_params]];  /* ASCII strings containing parameter values */
   png_byte pcal_type;      /* equation type (see PNG_EQUATION_ below) */
   png_byte pcal_nparams;   /* number of parameters given in pcal_params */
#endif /* PNG_READ_pCAL_SUPPORTED || PNG_WRITE_pCAL_SUPPORTED */
  --]=]
}

MAX_UINT = 0x7fffffff

COLOR_MASK_PALETTE = 1
COLOR_MASK_COLOR = 2
COLOR_MASK_ALPHA = 4

COLOR_TYPE_GRAY = 0
COLOR_TYPE_PALETTE = COLOR_MASK_COLOR + COLOR_MASK_PALETTE
COLOR_TYPE_RGB = COLOR_MASK_COLOR
COLOR_TYPE_RGB_ALPHA = COLOR_MASK_COLOR + COLOR_MASK_ALPHA
COLOR_TYPE_GRAY_ALPHA = COLOR_MASK_ALPHA

COMPRESSION_TYPE_BASE = 0
COMPRESSION_TYPE_DEFAULT = COMPRESSION_TYPE_BASE

FILTER_TYPE_BASE = 0
FILTER_TYPE_DEFAULT = FILTER_TYPE_BASE

INTERLACE_NONE = 0
INTERLACE_ADAM7 = 1

OFFSET_PIXEL = 0 -- Offset in pixels 
OFFSET_MICROMETER = 1 -- Offset in micrometers (1/10^6 meter) 
OFFSET_LAST = 2 -- Not a valid value 

-- These are for the pCAL chunk.  These values should NOT be changed. 
EQUATION_LINEAR = 0 -- Linear transformation 
EQUATION_BASE_E = 1 -- Exponential base e transform 
EQUATION_ARBITRARY = 2 -- Arbitrary base exponential transform 
EQUATION_HYPERBOLIC = 3 -- Hyperbolic sine transformation 
EQUATION_LAST = 4 -- Not a valid value 

-- These are for the pHYs chunk.  These values should NOT be changed. 
RESOLUTION_UNKNOWN = 0 -- pixels/unknown unit (aspect ratio) 
RESOLUTION_METER = 1 -- pixels/meter 
RESOLUTION_LAST = 2 -- Not a valid value 

-- These are for the sRGB chunk.  These values should NOT be changed. 
sRGB_INTENT_SATURATION = 0
sRGB_INTENT_PERCEPTUAL = 1
sRGB_INTENT_ABSOLUTE = 2
sRGB_INTENT_RELATIVE = 3
sRGB_INTENT_LAST = 4 -- Not a valid value 



--[[ These determine if an ancillary chunk's data has been successfully read
 * from the PNG header, or if the application has filled in the corresponding
 * data in the info_struct to be written into the output file.  The values
 * of the PNG_INFO_<chunk> defines should NOT be changed.
 --]]
INFO_gAMA = 0x0001
INFO_sBIT = 0x0002
INFO_cHRM = 0x0004
INFO_PLTE = 0x0008
INFO_tRNS = 0x0010
INFO_bKGD = 0x0020
INFO_hIST = 0x0040
INFO_pHYs = 0x0080
INFO_oFFs = 0x0100
INFO_tIME = 0x0200
INFO_pCAL = 0x0400
INFO_sRGB = 0x0800   -- GR-P, 0.96a 

local function Func(name, types)
  local func = lib["png_" .. name]
  func:types(types)
  _M[name] = func
  return func
end

-- Allocate and initialize png_ptr struct for reading, and any other memory.
Func("create_read_struct", {ret="pointer" --[[png_structp]]; 
  "string" --[[png_const_charp user_png_ver]],
  "pointer" --[[png_voidp error_ptr]],
  "callback" --[[png_error_ptr error_fn]],
  "callback" --[[png_error_ptr warn_fn]]})

-- Allocate and initialize the info structure
Func("create_info_struct", {ret="pointer" --[[png_infop]]; 
  "pointer" --[[png_structp png_ptr]]})

-- Allocate and initialize png_ptr struct for writing, and any other memory
Func("create_write_struct", {ret="pointer" --[[png_structp]]; 
  "pointer" --[[png_const_charp user_png_ver]],
  "pointer" --[[png_voidp error_ptr]],
  "callback" --[[png_error_ptr error_fn]],
  "callback" --[[png_error_ptr warn_fn]]})

row_info = alien.defstruct{
  {"width", "uint"};
  {"rowbytes", "uint"};
  {"color_type", "char"};
  {"bit_depth", "char"};
  {"channels", "char"};
  {"pixel_depth", "char"};
}

-- #if !defined(PNG_NO_STDIO)
-- Initialize the input/output for the PNG file to the default functions.
Func("init_io", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[FILE *fp]]})
-- #endif

-- Writes all the PNG information before the image.
Func("write_info", {ret="void";
  "pointer" --[[png_structp png_ptr]],
  "pointer" --[[png_infop info_ptr]]})

error_types = { ret="void"; "pointer" --[[png_structp]], "string" --[[png_const_charp]] }
rw_types = { ret="void"; "pointer" --[[png_structp]], "pointer" --[[png_bytep]], alienex.size_t }
flush_types = { ret="void"; "pointer" --[[png_structp]] }
read_status_types = { ret="void"; "pointer" --[[png_structp]], "uint", "int" }
write_status_types = { ret="void"; "pointer" --[[png_structp]], "uint", "int" }
--#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
progressive_info_types = { ret="void"; "pointer" --[[png_structp]], "pointer" --[[png_infop]] }
progressive_end_types = { ret="void"; "pointer" --[[png_structp]], "pointer" --[[png_infop]] }
progressive_row_types = { ret="void"; "pointer" --[[png_structp]], "pointer" --[[png_bytep]], "uint", "int" }
--#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */

--#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
user_transform_types = { ret="void"; "pointer" --[[png_structp]], "pointer" --[[png_row_infop]], "pointer" --[[png_bytep]] }
-- #endif /* PNG_READ|WRITE_USER_TRANSFORM_SUPPORTED */

--[[ Replace the default data output functions with a user supplied one(s).
 * If buffered output is not used, then output_flush_fn can be set to NULL.
 * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time
 * output_flush_fn will be ignored (and thus can be NULL).
 --]]
Func("set_write_fn", {ret="void";
  "pointer" --[[png_structp png_ptr]],
  "pointer" --[[png_voidp io_ptr]],
  "callback" --[[png_rw_ptr write_data_fn]],
  "pointer" --[[png_flush_ptr output_flush_fn]]})

-- Replace the default data input function with a user supplied one.
Func("set_read_fn", {ret="void";
  "pointer" --[[png_structp png_ptr]],
  "pointer" --[[png_voidp io_ptr]],
  "callback" --[[png_rw_ptr read_data_fn]]})

--[=[
malloc_types = { ret="pointer" --[[png_voidp]]; "pointer" --[[png_structp]], assert(size_t) }
--]=]
free_types = { ret="void"; "pointer" --[[png_structp]], "pointer" --[[png_voidp]] }

-- Fatal error in PNG image of libpng - can't continue
Func("error", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_const_charp error]]})

-- The same, but the chunk name is prepended to the error string.
Func("chunk_error", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_const_charp error]]})

-- Non-fatal error in libpng.  Can continue, but may have a problem.
Func("warning", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_const_charp message]]})

Func("set_IHDR", {ret="void";
  "pointer" --[[png_structp png_ptr]],
  "pointer" --[[png_infop info_ptr]],
  "uint" --[[width]],
  "uint" --[[height]],
  "int" --[[bit_depth]],
  "int" --[[color_type]],
  "int" --[[interlace_type]],
  "int" --[[compression_type]],
  "int" --[[filter_type]]})

-- Tell lib we have already handled the first <num_bytes> magic bytes.
-- Handling more than 8 bytes from the beginning of the file is an error.
Func("set_sig_bytes", {ret="void";
  "pointer" --[[png_structp png_ptr]],
  "int" --[[num_bytes]]})

-- read the information before the actual image data.
Func("read_info", {abi="stdcall"; ret="void";
  "pointer" --[[png_structp png_ptr]],
  "pointer" --[[png_infop info_ptr]]})

-- optional call to update the users info structure
Func("read_update_info", {ret="void";
  "pointer" --[[png_structp png_ptr]],
  "pointer" --[[png_infop info_ptr]]})

-- read a one or more rows of image data.
Func("read_rows", {ret="void";
  "pointer" --[[png_structp png_ptr]],
  "pointer" --[[png_bytepp row]],
  "pointer" --[[png_bytepp display_row]],
  "uint" --[[num_rows]]})

-- read a row of data.
Func("read_row", {ret="void";
  "pointer" --[[png_structp png_ptr]],
  "pointer" --[[png_bytep row]],
  "pointer" --[[png_bytep display_row]]})

-- write a row of image data
Func("write_row", {ret="void";
  "pointer" --[[png_structp png_ptr]],
  "pointer" --[[png_bytep row]]})

-- write a few rows of image data
Func("write_rows", {ret="void";
  "pointer" --[[png_structp png_ptr]],
  "pointer" --[[png_bytepp row]],
  "uint" --[[num_rows]]})

-- write the image data
Func("write_image", {ret="void";
  "pointer" --[[png_structp png_ptr]],
  "pointer" --[[png_bytepp image]]})

-- writes the end of the PNG file.
Func("write_end", {ret="void";
  "pointer" --[[png_structp png_ptr]],
  "pointer" --[[png_infop info_ptr]]})

-- #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
-- Use blue, green, red order for pixels.
Func("set_bgr", {ret="void"; "pointer" --[[png_structp png_ptr]]})
-- #endif -- PNG_READ_BGR_SUPPORTED || PNG_WRITE_BGR_SUPPORTED

-- #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
Func("set_strip_alpha", {ret="void"; "pointer" --[[png_structp png_ptr]]})
-- #endif -- PNG_READ_STRIP_ALPHA_SUPPORTED

-- #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
Func("set_swap_alpha", {ret="void"; "pointer" --[[png_structp png_ptr]]})
-- #endif -- PNG_READ_SWAP_ALPHA_SUPPORTED || PNG_WRITE_SWAP_ALPHA_SUPPORTED

-- #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
Func("set_invert_alpha", {ret="void"; "pointer" --[[png_structp png_ptr]]})
-- #endif -- PNG_READ_INVERT_ALPHA_SUPPORTED || PNG_WRITE_INVERT_ALPHA_SUPPORTED

-- #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
-- Add a filler byte to 24-bit RGB images.
Func("set_filler", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "uint" --[[filler]], "int" --[[flags]]})

-- The values of the PNG_FILLER_ defines should NOT be changed
FILLER_BEFORE = 0
FILLER_AFTER = 1
-- #endif -- PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED

-- #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
-- Swap bytes in 16-bit depth files.
Func("set_swap", {ret="void"; "pointer" --[[png_structp png_ptr]]})
-- #endif -- PNG_READ_SWAP_SUPPORTED || PNG_WRITE_SWAP_SUPPORTED

-- #if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
-- Use 1 byte per pixel in 1, 2, or 4-bit depth files.
Func("set_packing", {ret="void"; "pointer" --[[png_structp png_ptr]]})
-- #endif -- PNG_READ_PACK_SUPPORTED || PNG_WRITE_PACK_SUPPORTED

-- #if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED)
-- Swap packing order of pixels in bytes.
Func("set_packswap", {ret="void"; "pointer" --[[png_structp png_ptr]]})
-- #endif -- PNG_READ_PACKSWAP_SUPPORTED || PNG_WRITE_PACKSWAP_SUPPORTED

-- #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
-- Converts files to legal bit depths.
Func("set_shift", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_color_8p true_bits]]})
-- #endif -- PNG_READ_SHIFT_SUPPORTED || PNG_WRITE_SHIFT_SUPPORTED

-- #if defined(PNG_READ_INTERLACING_SUPPORTED) || defined(PNG_WRITE_INTERLACING_SUPPORTED)
-- Have the code handle the interlacing.  Returns the number of passes.
Func("set_interlace_handling", {ret="int"; "pointer" --[[png_structp png_ptr]]})
-- #endif -- PNG_READ_INTERLACING_SUPPORTED || PNG_WRITE_INTERLACING_SUPPORTED

-- #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
-- Invert monocrome files
Func("set_invert_mono", {ret="void"; "pointer" --[[png_structp png_ptr]]})
-- #endif -- PNG_READ_INVERT_SUPPORTED || PNG_WRITE_INVERT_SUPPORTED

-- #if defined(PNG_READ_BACKGROUND_SUPPORTED)
-- Handle alpha and tRNS by replacing with a background color.
Func("set_background", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_color_16p background_color]], "int" --[[background_gamma_code]],
   "int" --[[need_expand]], "double" --[[background_gamma]]})
BACKGROUND_GAMMA_UNKNOWN = 0
BACKGROUND_GAMMA_SCREEN = 1
BACKGROUND_GAMMA_FILE = 2
BACKGROUND_GAMMA_UNIQUE = 3
-- #endif -- PNG_READ_BACKGROUND_SUPPORTED

-- #if defined(PNG_READ_16_TO_8_SUPPORTED)
-- strip the second byte of information from a 16-bit depth file.
Func("set_strip_16", {ret="void"; "pointer" --[[png_structp png_ptr]]})
-- #endif -- PNG_READ_16_TO_8_SUPPORTED

-- #if defined(PNG_READ_DITHER_SUPPORTED)
-- Turn on dithering, and reduce the palette to the number of colors available.
Func("set_dither", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_colorp palette]], "int" --[[num_palette]], "int" --[[maximum_colors]],
   "pointer" --[[png_uint_16p histogram]], "int" --[[full_dither]]})
-- #endif -- PNG_READ_DITHER_SUPPORTED

-- #if defined(PNG_READ_GAMMA_SUPPORTED)
-- Handle gamma correction. Screen_gamma=(display_exponent)
Func("set_gamma", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "double" --[[screen_gamma]], "double" --[[default_file_gamma]]})
-- #endif -- PNG_READ_GAMMA_SUPPORTED

--[=====[

-- png_struct_def

--[[ Check sig[start] through sig[start + num_to_check - 1] to see if it's a
 * PNG file.  Returns zero if the supplied bytes match the 8-byte PNG
 * signature, and non-zero otherwise.  Having num_to_check == 0 or
 * start > 7 will always fail (ie return non-zero).
 --]]
Func("sig_cmp", {ret="int"; "pointer" --[[png_bytep sig]], png_size_t start,
   png_size_t num_to_check})

--[[ Simple signature checking function.  This is the same as calling
 * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n).
 --]]
Func("check_sig", {ret="int"; "pointer" --[[png_bytep sig]], "int" --[[num]]})

-- #ifdef PNG_USER_MEM_SUPPORTED
Func("create_read_struct_2", {ret="pointer" --[[png_structp]]; 
   "pointer" --[[png_const_charp user_png_ver]], "pointer" --[[png_voidp error_ptr]],
   "callback" --[[png_error_ptr error_fn]], "callback" --[[png_error_ptr warn_fn]], "pointer" --[[png_voidp mem_ptr]],
   "callback" --[[png_malloc_ptr malloc_fn]], "callback" --[[png_free_ptr free_fn]]})
Func("create_write_struct_2", {ret="pointer" --[[png_structp]]; 
   "pointer" --[[png_const_charp user_png_ver]], "pointer" --[[png_voidp error_ptr]],
   "callback" --[[png_error_ptr error_fn]], "callback" --[[png_error_ptr warn_fn]], "pointer" --[[png_voidp mem_ptr]],
   "callback" --[[png_malloc_ptr malloc_fn]], "callback" --[[png_free_ptr free_fn]]})
-- #endif

-- Write a PNG chunk - size, type, (optional) data, CRC.
Func("write_chunk", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_bytep chunk_name]], "pointer" --[[png_bytep data]], png_size_t length})

-- Write the start of a PNG chunk - length and chunk name.
Func("write_chunk_start", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_bytep chunk_name]], "uint" --[[length]]})

-- Write the data of a PNG chunk started with png_write_chunk_start().
Func("write_chunk_data", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_bytep data]], png_size_t length})

-- Finish a chunk started with png_write_chunk_start() (includes CRC).
Func("write_chunk_end", {ret="void"; "pointer" --[[png_structp png_ptr]]})

-- Initialize the info structure (old interface - NOT DLL EXPORTED)
extern void png_info_init "pointer" --[[png_infop info_ptr]]})

-- #if defined(PNG_TIME_RFC1123_SUPPORTED)
Func("convert_to_rfc1123", {ret="pointer" --[[png_charp]]; 
   "pointer" --[[png_structp png_ptr]], "pointer" --[[png_timep ptime]]})
-- #endif -- PNG_TIME_RFC1123_SUPPORTED

-- #if defined(PNG_WRITE_tIME_SUPPORTED)
-- convert from a struct tm to png_time
Func("convert_from_struct_tm", {ret="void"; "pointer" --[[png_timep ptime]],
   struct tm FAR * ttime})

-- convert from time_t to png_time.  Uses gmtime()
Func("convert_from_time_t", {ret="void"; "pointer" --[[png_timep ptime]],
   time_t ttime})
-- #endif -- PNG_WRITE_tIME_SUPPORTED

-- #if defined(PNG_READ_EXPAND_SUPPORTED)
-- Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available.
Func("set_expand", {ret="void"; "pointer" --[[png_structp png_ptr]]})
Func("set_gray_1_2_4_to_8", {ret="void"; "pointer" --[[png_structp png_ptr]]})
Func("set_palette_to_rgb", {ret="void"; "pointer" --[[png_structp png_ptr]]})
Func("set_tRNS_to_alpha", {ret="void"; "pointer" --[[png_structp png_ptr]]})
-- #endif -- PNG_READ_EXPAND_SUPPORTED

-- #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
-- Expand the grayscale to 24-bit RGB if necessary.
Func("set_gray_to_rgb", {ret="void"; "pointer" --[[png_structp png_ptr]]})
-- #endif -- PNG_READ_GRAY_TO_RGB_SUPPORTED

-- #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
-- Reduce RGB to grayscale.
Func("set_rgb_to_gray", {ret="void";
  "pointer" --[[png_structp png_ptr]],
  "int" --[[error_action]],
  "double" --[[red]],
  "double" --[[green]]})
Func("get_rgb_to_gray_status", {ret="png_byte"; "pointer" --[[png_structp png_ptr]]})
-- #endif -- PNG_READ_RGB_TO_GRAY_SUPPORTED

Func("build_grayscale_palette", {ret="void"; "int" --[[bit_depth]], "pointer" --[[png_colorp palette]]})


-- #if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
    defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
-- Permit or disallow empty PLTE (0: not permitted, 1: permitted)
Func("permit_empty_plte", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "int" --[[empty_plte_permitted]]})
-- #endif -- PNG_READ_EMPTY_PLTE_SUPPORTED

-- #if defined(PNG_WRITE_FLUSH_SUPPORTED)
-- Set how many lines between output flushes - 0 for no flushing
Func("set_flush", {ret="void"; "pointer" --[[png_structp png_ptr]], "int" --[[nrows]]})

-- Flush the current PNG output buffer
Func("write_flush", {ret="void"; "pointer" --[[png_structp png_ptr]]})
-- #endif -- PNG_WRITE_FLUSH_SUPPORTED

-- optional update palette with requested transformations
Func("start_read_image", {ret="void"; "pointer" --[[png_structp png_ptr]]})

-- read the whole image into memory at once.
Func("read_image", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_bytepp image]]})

-- read the end of the PNG file.
Func("read_end", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_infop info_ptr]]})

-- free any memory associated with the png_info_struct
Func("destroy_info_struct", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_infopp info_ptr_ptr]]})

-- free any memory associated with the png_struct and the png_info_structs
Func("destroy_read_struct", {ret="void";png_structpp
   png_ptr_ptr, "pointer" --[[png_infopp info_ptr_ptr]], "pointer" --[[png_infopp end_info_ptr_ptr]]})

-- free all memory used by the read (old method - NOT DLL EXPORTED)
extern void png_read_destroy "pointer" --[[png_structp png_ptr]], "pointer" --[[png_infop info_ptr]],
   "pointer" --[[png_infop end_info_ptr]]})

-- free any memory associated with the png_struct and the png_info_structs
Func("destroy_write_struct", {ret="void"; 
   "pointer" --[[png_structpp png_ptr_ptr]], "pointer" --[[png_infopp info_ptr_ptr]]})

-- free any memory used in info_ptr struct (old method - NOT DLL EXPORTED)
extern void png_write_destroy_info "pointer" --[[png_infop info_ptr]]})

-- free any memory used in png_ptr struct (old method - NOT DLL EXPORTED)
extern void png_write_destroy "pointer" --[[png_structp png_ptr]]})

-- set the libpng method of handling chunk CRC errors
Func("set_crc_action", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "int" --[[crit_action]], "int" --[[ancil_action]]})

--[[ Values for png_set_crc_action() to say how to handle CRC errors in
 * ancillary and critical chunks, and whether to use the data contained
 * therein.  Note that it is impossible to "discard" data in a critical
 * chunk.  For versions prior to 0.90, the action was always error/quit,
 * whereas in version 0.90 and later, the action for CRC errors in ancillary
 * chunks is warn/discard.  These values should NOT be changed.
 *
 *      value                       action:critical     action:ancillary
 --]]
CRC_DEFAULT        = 0  -- error/quit          warn/discard data
CRC_ERROR_QUIT     = 1  -- error/quit          error/quit       
CRC_WARN_DISCARD   = 2  -- (INVALID)           warn/discard data
CRC_WARN_USE       = 3  -- warn/use data       warn/use data    
CRC_QUIET_USE      = 4  -- quiet/use data      quiet/use data   
CRC_NO_CHANGE      = 5  -- use current value   use current value

--[[ These functions give the user control over the scan-line filtering in
 * libpng and the compression methods used by zlib.  These functions are
 * mainly useful for testing, as the defaults should work with most users.
 * Those users who are tight on memory or want faster performance at the
 * expense of compression can modify them.  See the compression library
 * header file (zlib.h) for an explination of the compression functions.
 --]]

--[[ set the filtering method(s) used by libpng.  Currently, the only valid
 * value for "method" is 0.
 --]]
Func("set_filter", {ret="void"; "pointer" --[[png_structp png_ptr]], "int" --[[method]],
   "int" --[[filters]]})

--[[ Flags for png_set_filter() to say which filters to use.  The flags
 * are chosen so that they don't conflict with real filter types
 * below, in case they are supplied instead of the #defined constants.
 * These values should NOT be changed.
 --]]
NO_FILTERS      = 0x00
FILTER_NONE     = 0x08
FILTER_SUB      = 0x10
FILTER_UP       = 0x20
FILTER_AVG      = 0x40
FILTER_PAETH    = 0x80
ALL_FILTERS  = (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \
                         PNG_FILTER_AVG | PNG_FILTER_PAETH)

--[[ Filter values (not flags) - used in pngwrite.c, pngwutil.c for now.
 * These defines should NOT be changed.
 --]]
FILTER_VALUE_NONE   = 0
FILTER_VALUE_SUB    = 1
FILTER_VALUE_UP     = 2
FILTER_VALUE_AVG    = 3
FILTER_VALUE_PAETH  = 4
FILTER_VALUE_LAST   = 5

-- #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) -- EXPERIMENTAL
--[[ The "heuristic_method" is given by one of the PNG_FILTER_HEURISTIC_
 * defines, either the default (minimum-sum-of-absolute-differences), or
 * the experimental method (weighted-minimum-sum-of-absolute-differences).
 *
 * Weights are factors >= 1.0, indicating how important it is to keep the
 * filter type consistent between rows.  Larger numbers mean the current
 * filter is that many times as likely to be the same as the "num_weights"
 * previous filters.  This is cumulative for each previous row with a weight.
 * There needs to be "num_weights" values in "filter_weights", or it can be
 * NULL if the weights aren't being specified.  Weights have no influence on
 * the selection of the first row filter.  Well chosen weights can (in theory)
 * improve the compression for a given image.
 *
 * Costs are factors >= 1.0 indicating the relative decoding costs of a
 * filter type.  Higher costs indicate more decoding expense, and are
 * therefore less likely to be selected over a filter with lower computational
 * costs.  There needs to be a value in "filter_costs" for each valid filter
 * type (given by PNG_FILTER_VALUE_LAST), or it can be NULL if you aren't
 * setting the costs.  Costs try to improve the speed of decompression without
 * unduly increasing the compressed image size.
 *
 * A negative weight or cost indicates the default value is to be used, and
 * values in the range [0.0, 1.0) indicate the value is to remain unchanged.
 * The default values for both weights and costs are currently 1.0, but may
 * change if good general weighting/cost heuristics can be found.  If both
 * the weights and costs are set to 1.0, this degenerates the WEIGHTED method
 * to the UNWEIGHTED method, but with added encoding time/computation.
 --]]
Func("set_filter_heuristics", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "int" --[[heuristic_method]], "int" --[[num_weights]], "pointer" --[[png_doublep filter_weights]],
   "pointer" --[[png_doublep filter_costs]]})
-- #endif --  PNG_WRITE_WEIGHTED_FILTER_SUPPORTED

--[[ Heuristic used for row filter selection.  These defines should NOT be
 * changed.
 --]]
FILTER_HEURISTIC_DEFAULT     = 0  -- Currently "UNWEIGHTED"
FILTER_HEURISTIC_UNWEIGHTED  = 1  -- Used by libpng < 0.95
FILTER_HEURISTIC_WEIGHTED    = 2  -- Experimental feature
FILTER_HEURISTIC_LAST        = 3  -- Not a valid value

--[[ Set the library compression level.  Currently, valid values range from
 * 0 - 9, corresponding directly to the zlib compression levels 0 - 9
 * (0 - no compression, 9 - "maximal" compression).  Note that tests have
 * shown that zlib compression levels 3-6 usually perform as well as level 9
 * for PNG images, and do considerably fewer caclulations.  In the future,
 * these values may not correspond directly to the zlib compression levels.
 --]]
Func("set_compression_level", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "int" --[[level]]})

Func("set_compression_mem_level", {ret="void"; 
   "pointer" --[[png_structp png_ptr]], "int" --[[mem_level]]})

Func("set_compression_strategy", {ret="void"; 
   "pointer" --[[png_structp png_ptr]], "int" --[[strategy]]})

Func("set_compression_window_bits", {ret="void"; 
   "pointer" --[[png_structp png_ptr]], "int" --[[window_bits]]})

Func("set_compression_method", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "int" --[[method]]})

--[[ These next functions are called for input/output, memory, and error
 * handling.  They are in the file pngrio.c, pngwio.c, and pngerror.c,
 * and call standard C I/O routines such as fread(), fwrite(), and
 * fprintf().  These functions can be made to use other I/O routines
 * at run time for those applications that need to handle I/O in a
 * different manner by calling png_set_???_fn().  See libpng.txt for
 * more information.
 --]]


--[[ Replace the (error and abort), and warning functions with user
 * supplied functions.  If no messages are to be printed you must still
 * write and use replacement functions. The replacement error_fn should
 * still do a longjmp to the last setjmp location if you are using this
 * method of error handling.  If error_fn or warning_fn is NULL, the
 * default function will be used.
 --]]

Func("set_error_fn", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_voidp error_ptr]], "callback" --[[png_error_ptr error_fn]], "callback" --[[png_error_ptr warning_fn]]})

-- Return the user pointer associated with the error functions
Func("get_error_ptr", {ret="pointer" --[[png_voidp]]; "pointer" --[[png_structp png_ptr]]})

-- Return the user pointer associated with the I/O functions
Func("get_io_ptr", {ret="pointer" --[[png_voidp]]; "pointer" --[[png_structp png_ptr]]})

Func("set_read_status_fn", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "callback" --[[png_read_status_ptr read_row_fn]]})

Func("set_write_status_fn", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "callback" --[[png_write_status_ptr write_row_fn]]})

-- #ifdef PNG_USER_MEM_SUPPORTED
-- Replace the default memory allocation functions with user supplied one(s).
Func("set_mem_fn", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_voidp mem_ptr]], "callback" --[[png_malloc_ptr malloc_fn]], "callback" --[[png_free_ptr free_fn]]})

-- Return the user pointer associated with the memory functions
Func("get_mem_ptr", {ret="pointer" --[[png_voidp]]; "pointer" --[[png_structp png_ptr]]})
-- #endif -- PNG_USER_MEM_SUPPORTED

-- #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
Func("set_read_user_transform_fn", {ret="void";png_structp
   png_ptr, "callback" --[[png_user_transform_ptr read_user_transform_fn]]})
-- #endif

-- #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
Func("set_write_user_transform_fn", {ret="void";png_structp
   png_ptr, "callback" --[[png_user_transform_ptr write_user_transform_fn]]})
-- #endif

-- #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
Func("set_user_transform_info", {ret="void";png_structp
   png_ptr, "pointer" --[[png_voidp user_transform_ptr]], "int" --[[user_transform_depth]],
   "int" --[[user_transform_channels]]})
-- Return the user pointer associated with the user transform functions
Func("get_user_transform_ptr", {ret="pointer" --[[png_voidp]]; 
   "pointer" --[[png_structp png_ptr]]})
-- #endif

-- #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
--[[ Sets the function callbacks for the push reader, and a pointer to a
 * user-defined structure available to the callback functions.
 --]]
Func("set_progressive_read_fn", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_voidp progressive_ptr]],
   "callback" --[[png_progressive_info_ptr info_fn]], "callback" --[[png_progressive_row_ptr row_fn]],
   "callback" --[[png_progressive_end_ptr end_fn]]})

-- returns the user pointer associated with the push read functions
Func("get_progressive_ptr", {ret="pointer" --[[png_voidp]]; 
   "pointer" --[[png_structp png_ptr]]})

-- function to be called when data becomes available
Func("process_data", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_infop info_ptr]], "pointer" --[[png_bytep buffer]], png_size_t buffer_size})

--[[ function that combines rows.  Not very much different than the
 * png_combine_row() call.  Is this even used?????
 --]]
Func("progressive_combine_row", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_bytep old_row]], "pointer" --[[png_bytep new_row]]})
-- #endif -- PNG_PROGRESSIVE_READ_SUPPORTED

Func("malloc", {ret="pointer" --[[png_voidp]]; "pointer" --[[png_structp png_ptr]],
   "uint" --[[size]]})

-- frees a pointer allocated by png_malloc()
Func("free", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_voidp ptr]]})

-- #ifdef PNG_USER_MEM_SUPPORTED
Func("malloc_default", {ret="pointer" --[[png_voidp]]; "pointer" --[[png_structp png_ptr]],
   "uint" --[[size]]})
Func("free_default", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_voidp ptr]]})
-- #endif -- PNG_USER_MEM_SUPPORTED

Func("memcpy_check", {ret="pointer" --[[png_voidp]]; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_voidp s]]1, "pointer" --[[png_voidp s]]2, "uint" --[[size]]})

Func("memset_check", {ret="pointer" --[[png_voidp]]; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_voidp s]]1, "int" --[[value]], "uint" --[[size]]})

-- #if defined(USE_FAR_KEYWORD)  -- memory model conversion function
extern void *png_far_to_near "pointer" --[[png_structp png_ptr]],"pointer" --[[png_voidp ptr]],
   "int" --[[check]]})
-- #endif -- USE_FAR_KEYWORD

-- Non-fatal error in libpng, chunk name is prepended to message.
Func("chunk_warning", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_const_charp message]]})

--[[ The png_set_<chunk> functions are for storing values in the png_info_struct.
 * Similarly, the png_get_<chunk> calls are used to read values from the
 * png_info_struct, either storing the parameters in the passed variables, or
 * setting pointers into the png_info_struct where the data is stored.  The
 * png_get_<chunk> functions return a non-zero value if the data was available
 * in info_ptr, or return zero and do not change any of the parameters if the
 * data was not available.
 *
 * These functions should be used instead of directly accessing png_info
 * to avoid problems with future changes in the size and internal layout of
 * png_info_struct.
 --]]
-- Returns "flag" if chunk data is valid in info_ptr.
Func("get_valid", {ret="uint"; "pointer" --[[png_structp png_ptr]],
"pointer" --[[png_infop info_ptr]], "uint" --[[flag]]})

-- Returns number of bytes needed to hold a transformed row.
Func("get_rowbytes", {ret="uint"; "pointer" --[[png_structp png_ptr]],
"pointer" --[[png_infop info_ptr]]})

-- Returns number of color channels in image.
Func("get_channels", {ret="png_byte"; "pointer" --[[png_structp png_ptr]],
"pointer" --[[png_infop info_ptr]]})

-- #ifdef PNG_EASY_ACCESS_SUPPORTED
-- Returns image width in pixels.
extern PNG_EXPORT(png_uint_32, png_get_image_width) png_structp
png_ptr, "pointer" --[[png_infop info_ptr]]})

-- Returns image height in pixels.
extern PNG_EXPORT(png_uint_32, png_get_image_height) png_structp
png_ptr, "pointer" --[[png_infop info_ptr]]})

-- Returns image bit_depth.
extern PNG_EXPORT(png_byte, png_get_bit_depth) png_structp
png_ptr, "pointer" --[[png_infop info_ptr]]})

-- Returns image color_type.
extern PNG_EXPORT(png_byte, png_get_color_type) png_structp
png_ptr, "pointer" --[[png_infop info_ptr]]})

-- Returns image filter_type.
extern PNG_EXPORT(png_byte, png_get_filter_type) png_structp
png_ptr, "pointer" --[[png_infop info_ptr]]})

-- Returns image interlace_type.
extern PNG_EXPORT(png_byte, png_get_interlace_type) png_structp
png_ptr, "pointer" --[[png_infop info_ptr]]})

-- Returns image compression_type.
extern PNG_EXPORT(png_byte, png_get_compression_type) png_structp
png_ptr, "pointer" --[[png_infop info_ptr]]})

-- Returns image resolution in pixels per meter, from pHYs chunk data.
extern PNG_EXPORT(png_uint_32, png_get_pixels_per_meter) png_structp
png_ptr, "pointer" --[[png_infop info_ptr]]})
extern PNG_EXPORT(png_uint_32, png_get_x_pixels_per_meter) png_structp
png_ptr, "pointer" --[[png_infop info_ptr]]})
extern PNG_EXPORT(png_uint_32, png_get_y_pixels_per_meter) png_structp
png_ptr, "pointer" --[[png_infop info_ptr]]})

-- Returns pixel aspect ratio, computed from pHYs chunk data. 
extern PNG_EXPORT(float, png_get_pixel_aspect_ratio) png_structp
png_ptr, "pointer" --[[png_infop info_ptr]]})

-- Returns image x, y offset in pixels or microns, from oFFs chunk data.
extern PNG_EXPORT(png_uint_32, png_get_x_offset_pixels) png_structp
png_ptr, "pointer" --[[png_infop info_ptr]]})
extern PNG_EXPORT(png_uint_32, png_get_y_offset_pixels) png_structp
png_ptr, "pointer" --[[png_infop info_ptr]]})
extern PNG_EXPORT(png_uint_32, png_get_x_offset_microns) png_structp
png_ptr, "pointer" --[[png_infop info_ptr]]})
extern PNG_EXPORT(png_uint_32, png_get_y_offset_microns) png_structp
png_ptr, "pointer" --[[png_infop info_ptr]]})

-- #endif -- PNG_EASY_ACCESS_SUPPORTED

-- Returns pointer to signature string read from PNG header
Func("get_signature", {ret="pointer" --[[png_bytep]];"pointer" --[[png_structp png_ptr]],
"pointer" --[[png_infop info_ptr]]})

-- #if defined(PNG_READ_bKGD_SUPPORTED)
Func("get_bKGD", {ret="uint"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_infop info_ptr]], png_color_16p *background})
-- #endif -- PNG_READ_bKGD_SUPPORTED

-- #if defined(PNG_READ_bKGD_SUPPORTED) || defined(PNG_WRITE_bKGD_SUPPORTED)
Func("set_bKGD", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_infop info_ptr]], "pointer" --[[png_color_16p background]]})
-- #endif -- PNG_READ_bKGD_SUPPORTED || PNG_WRITE_bKGD_SUPPORTED

-- #if defined(PNG_READ_cHRM_SUPPORTED)
Func("get_cHRM", {ret="uint"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_infop info_ptr]], double *white_x, double *white_y, double *red_x,
   double *red_y, double *green_x, double *green_y, double *blue_x,
   double *blue_y})
-- #endif -- PNG_READ_cHRM_SUPPORTED

-- #if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED)
Func("set_cHRM", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_infop info_ptr]], "double" --[[white_x]], "double" --[[white_y]], "double" --[[red_x]],
   "double" --[[red_y]], "double" --[[green_x]], "double" --[[green_y]], "double" --[[blue_x]], "double" --[[blue_y]]})
-- #endif -- PNG_READ_cHRM_SUPPORTED || PNG_WRITE_cHRM_SUPPORTED

-- #if defined(PNG_READ_gAMA_SUPPORTED)
Func("get_gAMA", {ret="uint"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_infop info_ptr]], double *file_gamma})
-- #endif -- PNG_READ_gAMA_SUPPORTED

-- #if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED)
Func("set_gAMA", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_infop info_ptr]], "double" --[[file_gamma]]})
-- #endif -- PNG_READ_gAMA_SUPPORTED || PNG_WRITE_gAMA_SUPPORTED

-- #if defined(PNG_READ_hIST_SUPPORTED)
Func("get_hIST", {ret="uint"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_infop info_ptr]], png_uint_16p *hist})
-- #endif -- PNG_READ_hIST_SUPPORTED

-- #if defined(PNG_READ_hIST_SUPPORTED) || defined(PNG_WRITE_hIST_SUPPORTED)
Func("set_hIST", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_infop info_ptr]], "pointer" --[[png_uint_16p hist]]})
-- #endif -- PNG_READ_hIST_SUPPORTED || PNG_WRITE_hIST_SUPPORTED

Func("get_IHDR", {ret="uint"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_infop info_ptr]], png_uint_32 *width, png_uint_32 *height,
   int *bit_depth, int *color_type, int *interlace_type,
   int *compression_type, int *filter_type})

-- #if defined(PNG_READ_oFFs_SUPPORTED)
Func("get_oFFs", {ret="uint"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_infop info_ptr]], png_uint_32 *offset_x, png_uint_32 *offset_y,
   int *unit_type})
-- #endif -- PNG_READ_oFFs_SUPPORTED

-- #if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
Func("set_oFFs", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_infop info_ptr]], "uint" --[[offset_x]], "uint" --[[offset_y]],
   "int" --[[unit_type]]})
-- #endif -- PNG_READ_oFFs_SUPPORTED || PNG_WRITE_oFFs_SUPPORTED

-- #if defined(PNG_READ_pCAL_SUPPORTED)
Func("get_pCAL", {ret="uint"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_infop info_ptr]], png_charp *purpose, png_int_32 *X0, png_int_32 *X1,
   int *type, int *nparams, png_charp *units, png_charpp *params})
-- #endif -- PNG_READ_pCAL_SUPPORTED

-- #if defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED)
Func("set_pCAL", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_infop info_ptr]], "pointer" --[[png_charp purpose]], png_int_32 X0, png_int_32 X1,
   "int" --[[type]], "int" --[[nparams]], "pointer" --[[png_charp units]], "pointer" --[[png_charpp params]]})
-- #endif -- PNG_READ_pCAL_SUPPORTED || PNG_WRITE_pCAL_SUPPORTED

-- #if defined(PNG_READ_pHYs_SUPPORTED)
Func("get_pHYs", {ret="uint"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_infop info_ptr]], png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type})
-- #endif -- PNG_READ_pHYs_SUPPORTED

-- #if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
Func("set_pHYs", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_infop info_ptr]], "uint" --[[res_x]], "uint" --[[res_y]], "int" --[[unit_type]]})
-- #endif -- PNG_READ_pHYs_SUPPORTED || PNG_WRITE_pHYs_SUPPORTED

Func("get_PLTE", {ret="uint"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_infop info_ptr]], png_colorp *palette, int *num_palette})

Func("set_PLTE", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_infop info_ptr]], "pointer" --[[png_colorp palette]], "int" --[[num_palette]]})

-- #if defined(PNG_READ_sBIT_SUPPORTED)
Func("get_sBIT", {ret="uint"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_infop info_ptr]], png_color_8p *sig_bit})
-- #endif -- PNG_READ_sBIT_SUPPORTED

-- #if defined(PNG_READ_sBIT_SUPPORTED) || defined(PNG_WRITE_sBIT_SUPPORTED)
Func("set_sBIT", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_infop info_ptr]], "pointer" --[[png_color_8p sig_bit]]})
-- #endif -- PNG_READ_sBIT_SUPPORTED || PNG_WRITE_sBIT_SUPPORTED

-- #if defined(PNG_READ_sRGB_SUPPORTED)
Func("get_sRGB", {ret="uint"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_infop info_ptr]], int *intent})
-- #endif -- PNG_READ_sRGB_SUPPORTED

-- #if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
Func("set_sRGB", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_infop info_ptr]], "int" --[[intent]]})
Func("set_sRGB_gAMA_and_cHRM", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_infop info_ptr]], "int" --[[intent]]})
-- #endif -- PNG_READ_sRGB_SUPPORTED || PNG_WRITE_sRGB_SUPPORTED

-- #if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
-- png_get_text also returns the number of text chunks in text_ptr
Func("get_text", {ret="uint"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_infop info_ptr]], png_textp *text_ptr, int *num_text})
-- #endif -- PNG_READ_tEXt_SUPPORTED || PNG_READ_zTXt_SUPPORTED

-- #if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \
    defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
Func("set_text", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_infop info_ptr]], "pointer" --[[png_textp text_ptr]], "int" --[[num_text]]})
-- #endif -- PNG_READ_OR_WRITE_tEXt_OR_zTXt_SUPPORTED

-- #if defined(PNG_READ_tIME_SUPPORTED)
Func("get_tIME", {ret="uint"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_infop info_ptr]], png_timep *mod_time})
-- #endif -- PNG_READ_tIME_SUPPORTED

-- #if defined(PNG_READ_tIME_SUPPORTED) || defined(PNG_WRITE_tIME_SUPPORTED)
Func("set_tIME", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_infop info_ptr]], "pointer" --[[png_timep mod_time]]})
-- #endif -- PNG_READ_tIME_SUPPORTED || PNG_WRITE_tIME_SUPPORTED

-- #if defined(PNG_READ_tRNS_SUPPORTED)
Func("get_tRNS", {ret="uint"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_infop info_ptr]], png_bytep *trans, int *num_trans,
   png_color_16p *trans_values})
-- #endif -- PNG_READ_tRNS_SUPPORTED

-- #if defined(PNG_READ_tRNS_SUPPORTED) || defined(PNG_WRITE_tRNS_SUPPORTED)
Func("set_tRNS", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_infop info_ptr]], "pointer" --[[png_bytep trans]], "int" --[[num_trans]],
   "pointer" --[[png_color_16p trans_values]]})
-- #endif -- PNG_READ_tRNS_SUPPORTED || PNG_WRITE_tRNS_SUPPORTED

--[[ Define PNG_DEBUG at compile time for debugging information.  Higher
 * numbers for PNG_DEBUG mean more debugging information.  This has
 * only been added since version 0.95 so it is not implemented throughout
 * libpng yet, but more support will be added as needed.
 --]]
-- #ifdef PNG_DEBUG
-- #if (PNG_DEBUG > 0)
-- #ifndef PNG_DEBUG_FILE
DEBUG_FILE  = stderr
-- #endif -- PNG_DEBUG_FILE

#define png_debug(l,m)        if (PNG_DEBUG > l) \
                                 fprintf(PNG_DEBUG_FILE,"%s"m,(l==1 ? "\t" : \
                                    (l==2 ? "\t\t":(l>2 ? "\t\t\t":""))))
#define png_debug1(l,m,p1)    if (PNG_DEBUG > l) \
                                 fprintf(PNG_DEBUG_FILE,"%s"m,(l==1 ? "\t" : \
                                    (l==2 ? "\t\t":(l>2 ? "\t\t\t":""))),p1)
#define png_debug2(l,m,p1,p2) if (PNG_DEBUG > l) \
                                 fprintf(PNG_DEBUG_FILE,"%s"m,(l==1 ? "\t" : \
                                    (l==2 ? "\t\t":(l>2 ? "\t\t\t":""))),p1,p2)
-- #endif -- (PNG_DEBUG > 0)
-- #endif -- PNG_DEBUG
-- #ifndef png_debug
#define png_debug(l, m)
-- #endif
-- #ifndef png_debug1
#define png_debug1(l, m, p1)
-- #endif
-- #ifndef png_debug2
#define png_debug2(l, m, p1, p2)
-- #endif

Func("get_copyright", {ret="pointer" --[[png_charp]]; "pointer" --[[png_structp png_ptr]]})
Func("get_header_version", {ret="pointer" --[[png_charp]]; "pointer" --[[png_structp png_ptr]]})

-- #ifdef PNG_NO_EXTERN
-- this only gets included in png.c

GET_HEADER  = \
png_charp \
png_get_header_version("pointer" --[[png_structp png_ptr]]) \
{ \
   if(png_ptr != NULL) -- silence compiler warning about unused png_ptr \
      return("\n libpng version 1.0.5 - October 15, 1999 (header)\n"); \
   return("\n libpng version 1.0.5 - October 15, 1999 (header)\n"); \
}
-- #endif

-- #ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED
--[[ With these routines we avoid an integer divide, which will be slower on
 * most machines.  However, it does take more operations than the corresponding
 * divide method, so it may be slower on a few RISC systems.  There are two
 * shifts (by 8 or 16 bits) and an addition, versus a single integer divide.
 *
 * Note that the rounding factors are NOT supposed to be the same!  128 and
 * 32768 are correct for the NODIV code; 127 and 32767 are correct for the
 * standard method.
 *
 * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ]
 --]]

 -- fg and bg should be in `gamma 1.0' space; alpha is the opacity         

#  define png_composite(composite, fg, alpha, bg)                            \
     { "ushort" --[[temp]] = (png_uint_16)((png_uint_16)(fg) * (png_uint_16)(alpha) \
                        +        (png_uint_16)(bg)*(png_uint_16)(255 -       \
                        (png_uint_16)(alpha)) + (png_uint_16)128);           \
       (composite) = (png_byte)((temp + (temp >> 8)) >> 8); }

#  define png_composite_16(composite, fg, alpha, bg)                         \
     { "uint" --[[temp]] = (png_uint_32)((png_uint_32)(fg) * (png_uint_32)(alpha) \
                        + (png_uint_32)(bg)*(png_uint_32)(65535L -           \
                        (png_uint_32)(alpha)) + (png_uint_32)32768L);        \
       (composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); }

-- #else  -- standard method using integer division

#  define png_composite(composite, fg, alpha, bg)                            \
     (composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) +    \
       (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) +       \
       (png_uint_16)127) / 255)

#  define png_composite_16(composite, fg, alpha, bg)                         \
     (composite) = (png_uint_16)(((png_uint_32)(fg) * (png_uint_32)(alpha) + \
       (png_uint_32)(bg)*(png_uint_32)(65535L - (png_uint_32)(alpha)) +      \
       (png_uint_32)32767) / (png_uint_32)65535L)

-- #endif -- PNG_READ_COMPOSITE_NODIV_SUPPORTED

--[[ These next functions are used internally in the code.  They generally
 * shouldn't be used unless you are writing code to add or replace some
 * functionality in libpng.  More information about most functions can
 * be found in the files where the functions are located.
 --]]

-- #if defined(PNG_INTERNAL)

--[[ Various modes of operation.  Note that after an init, mode is set to
 * zero automatically when the structure is created.
 --]]
BEFORE_IHDR        = 0x00
HAVE_IHDR          = 0x01
HAVE_PLTE          = 0x02
HAVE_IDAT          = 0x04
AFTER_IDAT         = 0x08
HAVE_IEND          = 0x10
HAVE_gAMA          = 0x20
HAVE_cHRM          = 0x40
HAVE_sRGB          = 0x80

-- push model modes
READ_SIG_MODE    = 0
READ_CHUNK_MODE  = 1
READ_IDAT_MODE   = 2
SKIP_MODE        = 3
READ_tEXt_MODE   = 4
READ_zTXt_MODE   = 5
READ_DONE_MODE   = 6
ERROR_MODE       = 7

-- flags for the transformations the PNG library does on the image data
BGR                 = 0x0001
INTERLACE           = 0x0002
PACK                = 0x0004
SHIFT               = 0x0008
SWAP_BYTES          = 0x0010
INVERT_MONO         = 0x0020
DITHER              = 0x0040
BACKGROUND          = 0x0080
BACKGROUND_EXPAND   = 0x0100
--   0x0200 unused
_16_TO_8             = 0x0400
RGBA                = 0x0800
EXPAND              = 0x1000
GAMMA               = 0x2000
GRAY_TO_RGB         = 0x4000
FILLER              = 0x8000
PACKSWAP           = 0x10000
SWAP_ALPHA         = 0x20000
STRIP_ALPHA        = 0x40000
INVERT_ALPHA       = 0x80000
USER_TRANSFORM    = 0x100000
RGB_TO_GRAY_ERR   = 0x200000
RGB_TO_GRAY_WARN  = 0x400000
RGB_TO_GRAY       = 0x600000  -- two bits, RGB_TO_GRAY_ERR|WARN

-- flags for png_create_struct
STRUCT_PNG    = 0x0001
STRUCT_INFO   = 0x0002

-- Scaling factor for filter heuristic weighting calculations
WEIGHT_SHIFT  = 8
WEIGHT_FACTOR  = bit.lshift(1, PNG_WEIGHT_SHIFT)
COST_SHIFT  = 3
COST_FACTOR  = bit.lshift(1, PNG_COST_SHIFT)

-- flags for the png_ptr->flags rather than declaring a byte for each one
FLAG_ZLIB_CUSTOM_STRATEGY      = 0x0001
FLAG_ZLIB_CUSTOM_LEVEL         = 0x0002
FLAG_ZLIB_CUSTOM_MEM_LEVEL     = 0x0004
FLAG_ZLIB_CUSTOM_WINDOW_BITS   = 0x0008
FLAG_ZLIB_CUSTOM_METHOD        = 0x0010
FLAG_ZLIB_FINISHED             = 0x0020
FLAG_ROW_INIT                  = 0x0040
FLAG_FILLER_AFTER              = 0x0080
FLAG_CRC_ANCILLARY_USE         = 0x0100
FLAG_CRC_ANCILLARY_NOWARN      = 0x0200
FLAG_CRC_CRITICAL_USE          = 0x0400
FLAG_CRC_CRITICAL_IGNORE       = 0x0800
FLAG_FREE_PALETTE              = 0x1000
FLAG_FREE_TRANS                = 0x2000
FLAG_FREE_HIST                 = 0x4000
FLAG_HAVE_CHUNK_HEADER         = 0x8000
FLAG_WROTE_tIME               = 0x10000
FLAG_BACKGROUND_IS_GRAY       = 0x20000

FLAG_CRC_ANCILLARY_MASK  = (PNG_FLAG_CRC_ANCILLARY_USE | \
                                     PNG_FLAG_CRC_ANCILLARY_NOWARN)

FLAG_CRC_CRITICAL_MASK   = (PNG_FLAG_CRC_CRITICAL_USE | \
                                     PNG_FLAG_CRC_CRITICAL_IGNORE)

FLAG_CRC_MASK            = (PNG_FLAG_CRC_ANCILLARY_MASK | \
                                     PNG_FLAG_CRC_CRITICAL_MASK)

-- save typing and make code easier to understand
#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \
   abs((int)((c1).green) - (int)((c2).green)) + \
   abs((int)((c1).blue) - (int)((c2).blue)))

--[==[
-- variables declared in png.c - only it needs to define PNG_NO_EXTERN
-- #if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN)
-- place to hold the signature string for a PNG file.
extern png_byte FARDATA png_sig[8];

--[[ Constant strings for known chunk types.  If you need to add a chunk,
 * add a string holding the name here.  See png.c for more details.  We
 * can't selectively include these, since we still check for chunk in the
 * wrong locations with these labels.
 --]]
extern png_byte FARDATA png_IHDR[5];
extern png_byte FARDATA png_IDAT[5];
extern png_byte FARDATA png_IEND[5];
extern png_byte FARDATA png_PLTE[5];
extern png_byte FARDATA png_bKGD[5];
extern png_byte FARDATA png_cHRM[5];
extern png_byte FARDATA png_gAMA[5];
extern png_byte FARDATA png_hIST[5];
extern png_byte FARDATA png_oFFs[5];
extern png_byte FARDATA png_pCAL[5];
extern png_byte FARDATA png_pHYs[5];
extern png_byte FARDATA png_sBIT[5];
extern png_byte FARDATA png_sRGB[5];
extern png_byte FARDATA png_tEXt[5];
extern png_byte FARDATA png_tIME[5];
extern png_byte FARDATA png_tRNS[5];
extern png_byte FARDATA png_zTXt[5];
--]==]

-- #endif -- PNG_NO_EXTERN

--[[ Inline macros to do direct reads of bytes from the input buffer.  These
 * require that you are using an architecture that uses PNG byte ordering
 * (MSB first) and supports unaligned data storage.  I think that PowerPC
 * in big-endian mode and 680x0 are the only ones that will support this.
 * The x86 line of processors definitely do not.  The png_get_int_32()
 * routine also assumes we are using two's complement format for negative
 * values, which is almost certainly true.
 --]]
-- #if defined(PNG_READ_BIG_ENDIAN_SUPPORTED)
-- #if defined(PNG_READ_pCAL_SUPPORTED)
#define png_get_int_32(buf) ( *((png_int_32p) (buf)))
-- #endif -- PNG_READ_pCAL_SUPPORTED
#define png_get_uint_32(buf) ( *((png_uint_32p) (buf)))
#define png_get_uint_16(buf) ( *((png_uint_16p) (buf)))
-- #else
-- #if defined(PNG_READ_pCAL_SUPPORTED)
PNG_EXTERN png_int_32 png_get_int_32 "pointer" --[[png_bytep buf]]})
-- #endif -- PNG_READ_pCAL_SUPPORTED
PNG_EXTERN "uint" --[[png_get_uint_32]] "pointer" --[[png_bytep buf]]})
PNG_EXTERN "ushort" --[[png_get_uint_16]] "pointer" --[[png_bytep buf]]})
-- #endif -- PNG_READ_BIG_ENDIAN_SUPPORTED

--[[ Initialize png_ptr struct for reading, and allocate any other memory.
 * (old interface - NOT DLL EXPORTED).
 --]]
extern void png_read_init "pointer" --[[png_structp png_ptr]]})

--[[ Initialize png_ptr struct for writing, and allocate any other memory.
 * (old interface - NOT DLL EXPORTED).
 --]]
extern void png_write_init "pointer" --[[png_structp png_ptr]]})

-- allocate memory for an internal libpng struct
PNG_EXTERN "pointer" --[[png_voidp png_create_struct]] "int" --[[type]]})

-- free memory from internal libpng struct
Func("destroy_struct", {ret="void"; "pointer" --[[png_voidp struct_ptr]]})
Func("create_struct_2", {ret="pointer" --[[png_voidp]]; "int" --[[type]], "callback" --[[png_malloc_ptr malloc_fn]]})
Func("destroy_struct_2", {ret="void"; "pointer" --[[png_voidp struct_ptr]], "callback" --[[png_free_ptr free_fn]]})

-- free any memory that info_ptr points to and reset struct.
Func("info_destroy", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_infop info_ptr]]})

-- Function to allocate memory for zlib.
Func("zalloc", {ret="pointer" --[[voidpf]]; "pointer" --[[voidpf png_ptr]], "uint" --[[items]], "uint" --[[size]]})

-- function to free memory for zlib
Func("zfree", {ret="void"; voidpf png_ptr, voidpf ptr})

-- reset the CRC variable
Func("reset_crc", {ret="void"; "pointer" --[[png_structp png_ptr]]})

-- Write the "data" buffer to whatever output you are using.
Func("write_data", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_bytep data]],
   png_size_t length})

-- Read data from whatever input you are using into the "data" buffer
Func("read_data", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_bytep data]],
   png_size_t length})

-- read bytes into buf, and update png_ptr->crc
Func("crc_read", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_bytep buf]],
   png_size_t length})

-- read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc
Func("crc_finish", {ret="int"; "pointer" --[[png_structp png_ptr]], "uint" --[[skip]]})

-- read the CRC from the file and compare it to the libpng calculated CRC
Func("crc_error", {ret="int"; "pointer" --[[png_structp png_ptr]]})

--[[ Calculate the CRC over a section of data.  Note that we are only
 * passing a maximum of 64K on systems that have this as a memory limit,
 * since this is the maximum buffer size we can specify.
 --]]
Func("calculate_crc", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_bytep ptr]],
   png_size_t length})

-- #if defined(PNG_WRITE_FLUSH_SUPPORTED)
Func("flush", {ret="void"; "pointer" --[[png_structp png_ptr]]})
-- #endif

--[[ Place a 32-bit number into a buffer in PNG byte order (big-endian).
 * The only currently known PNG chunks that use signed numbers are
 * the ancillary extension chunks, oFFs and pCAL.
 --]]
Func("save_uint_32", {ret="void"; "pointer" --[[png_bytep buf]], "uint"})

-- #if defined(PNG_WRITE_pCAL_SUPPORTED)
Func("save_int_32", {ret="void"; "pointer" --[[png_bytep buf]], "int"})
-- #endif

--[[ Place a 16-bit number into a buffer in PNG byte order.
 * The parameter is declared unsigned int, not png_uint_16,
 * just to avoid potential problems on pre-ANSI C compilers.
 --]]
Func("save_uint_16", {ret="void"; "pointer" --[[png_bytep buf]], "ushort"})

-- simple function to write the signature
Func("write_sig", {ret="void";
  "pointer" --[[png_structp png_ptr]]})

-- write various chunks

--[[ Write the IHDR chunk, and update the png_struct with the necessary
 * information.
 --]]
Func("write_IHDR", {ret="void";
  "pointer" --[[png_structp png_ptr]],
  "uint" --[[width]],
  "uint" --[[height]],
  "int" --[[bit_depth]],
  "int" --[[color_type]],
  "int" --[[compression_type]],
  "int" --[[filter_type]],
  "int" --[[interlace_type]]})

Func("write_PLTE", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_colorp palette]],
   "uint" --[[num_pal]]})

Func("write_IDAT", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_bytep data]],
   png_size_t length})

Func("write_IEND", {ret="void"; "pointer" --[[png_structp png_ptr]]})

-- #if defined(PNG_WRITE_gAMA_SUPPORTED)
Func("write_gAMA", {ret="void"; "pointer" --[[png_structp png_ptr]], "double" --[[file_gamma]]})
-- #endif

-- #if defined(PNG_WRITE_sBIT_SUPPORTED)
Func("write_sBIT", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_color_8p sbit]],
   "int" --[[color_type]]})
-- #endif

-- #if defined(PNG_WRITE_cHRM_SUPPORTED)
Func("write_cHRM", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "double" --[[white_x]], "double" --[[white_y]],
   "double" --[[red_x]], "double" --[[red_y]], "double" --[[green_x]], "double" --[[green_y]],
   "double" --[[blue_x]], "double" --[[blue_y]]})
-- #endif

-- #if defined(PNG_WRITE_sRGB_SUPPORTED)
Func("write_sRGB", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "int" --[[intent]]})
-- #endif

-- #if defined(PNG_WRITE_tRNS_SUPPORTED)
Func("write_tRNS", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_bytep trans]],
   "pointer" --[[png_color_16p values]], "int" --[[number]], "int" --[[color_type]]})
-- #endif

-- #if defined(PNG_WRITE_bKGD_SUPPORTED)
Func("write_bKGD", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_color_16p values]], "int" --[[color_type]]})
-- #endif

-- #if defined(PNG_WRITE_hIST_SUPPORTED)
Func("write_hIST", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_uint_16p hist]],
   "int" --[[num_hist]]})
-- #endif

-- #if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED) || \
    defined(PNG_WRITE_pCAL_SUPPORTED)
PNG_EXTERN png_size_t png_check_keyword "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_charp key]], "pointer" --[[png_charpp new_key]]})
-- #endif

-- #if defined(PNG_WRITE_tEXt_SUPPORTED)
Func("write_tEXt", {ret="void";
  "pointer" --[[png_structp png_ptr]],
  "pointer" --[[png_charp key]],
  "pointer" --[[png_charp text]],
  png_size_t text_len})
-- #endif

-- #if defined(PNG_WRITE_zTXt_SUPPORTED)
Func("write_zTXt", {ret="void";
  "pointer" --[[png_structp png_ptr]],
  "pointer" --[[png_charp key]],
  "pointer" --[[png_charp text]],
  png_size_t text_len,
  "int" --[[compression]]})
-- #endif

-- #if defined(PNG_WRITE_oFFs_SUPPORTED)
Func("write_oFFs", {ret="void";
  "pointer" --[[png_structp png_ptr]],
  "uint" --[[x_offset]],
  "uint" --[[y_offset]],
  "int" --[[unit_type]]})
-- #endif

-- #if defined(PNG_WRITE_pCAL_SUPPORTED)
Func("write_pCAL", {ret="void";
  "pointer" --[[png_structp png_ptr]],
  "pointer" --[[png_charp purpose]],
  "int" --[[X0]],
  "int" --[[X1]],
  "int" --[[type]],
  "int" --[[nparams]],
  "pointer" --[[png_charp units]],
  "pointer" --[[png_charpp params]]})
-- #endif

-- #if defined(PNG_WRITE_pHYs_SUPPORTED)
Func("write_pHYs", {ret="void";
  "pointer" --[[png_structp png_ptr]],
  "uint" --[[x_pixels_per_unit]],
  "uint" --[[y_pixels_per_unit]],
  "int" --[[unit_type]]})
-- #endif

-- #if defined(PNG_WRITE_tIME_SUPPORTED)
Func("write_tIME", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_timep mod_time]]})
-- #endif

-- Called when finished processing a row of data
Func("write_finish_row", {ret="void"; "pointer" --[[png_structp png_ptr]]})

-- Internal use only.   Called before first row of data
Func("write_start_row", {ret="void"; "pointer" --[[png_structp png_ptr]]})

-- #if defined(PNG_READ_GAMMA_SUPPORTED)
Func("build_gamma_table", {ret="void"; "pointer" --[[png_structp png_ptr]]})
-- #endif

-- combine a row of data, dealing with alpha, etc. if requested
Func("combine_row", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_bytep row]], "int" --[[mask]]})

-- #if defined(PNG_READ_INTERLACING_SUPPORTED)
-- expand an interlaced row
Func("do_read_interlace", {ret="void"; "pointer" --[[png_row_infop row_info]],
   "pointer" --[[png_bytep row]], "int" --[[pass]], "uint" --[[transformations]]})
-- #endif

-- #if defined(PNG_WRITE_INTERLACING_SUPPORTED)
-- grab pixels out of a row for an interlaced pass
Func("do_write_interlace", {ret="void"; "pointer" --[[png_row_infop row_info]],
   "pointer" --[[png_bytep row]], "int" --[[pass]]})
-- #endif

-- unfilter a row
Func("read_filter_row", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_row_infop row_info]], "pointer" --[[png_bytep row]], "pointer" --[[png_bytep prev_row]], "int" --[[filter]]})

-- Choose the best filter to use and filter the row data
Func("write_find_filter", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_row_infop row_info]]})

-- Write out the filtered row.
Func("write_filtered_row", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_bytep filtered_row]]})
-- finish a row while reading, dealing with interlacing passes, etc.
Func("read_finish_row", {ret="void"; "pointer" --[[png_structp png_ptr]]})

-- initialize the row buffers, etc.
Func("read_start_row", {ret="void"; "pointer" --[[png_structp png_ptr]]})
-- optional call to update the users info structure
Func("read_transform_info", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_infop info_ptr]]})

-- these are the functions that do the transformations
-- #if defined(PNG_READ_FILLER_SUPPORTED)
Func("do_read_filler", {ret="void"; "pointer" --[[png_row_infop row_info]],
   "pointer" --[[png_bytep row]], "uint" --[[filler]], "uint" --[[flags]]})
-- #endif

-- #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
Func("do_read_swap_alpha", {ret="void"; "pointer" --[[png_row_infop row_info]],
   "pointer" --[[png_bytep row]]})
-- #endif

-- #if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
Func("do_write_swap_alpha", {ret="void"; "pointer" --[[png_row_infop row_info]],
   "pointer" --[[png_bytep row]]})
-- #endif

-- #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
Func("do_read_invert_alpha", {ret="void"; "pointer" --[[png_row_infop row_info]],
   "pointer" --[[png_bytep row]]})
-- #endif

-- #if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
Func("do_write_invert_alpha", {ret="void"; "pointer" --[[png_row_infop row_info]],
   "pointer" --[[png_bytep row]]})
-- #endif

-- #if defined(PNG_WRITE_FILLER_SUPPORTED) || \
    defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
Func("do_strip_filler", {ret="void"; "pointer" --[[png_row_infop row_info]],
   "pointer" --[[png_bytep row]], "uint" --[[flags]]})
-- #endif

-- #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
PNG_EXTERN void "pointer" --[[png_do_swap PNGARG]](("pointer" --[[png_row_infop row_info]], "pointer" --[[png_bytep row]]})
-- #endif

-- #if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED)
PNG_EXTERN void "pointer" --[[png_do_packswap PNGARG]](("pointer" --[[png_row_infop row_info]], "pointer" --[[png_bytep row]]})
-- #endif

-- #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
Func("do_rgb_to_gray", {ret="int"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_row_infop row_info]], "pointer" --[[png_bytep row]]})
-- #endif

-- #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
Func("do_gray_to_rgb", {ret="void"; "pointer" --[[png_row_infop row_info]], "pointer" --[[png_bytep row]]})
-- #endif

-- #if defined(PNG_READ_PACK_SUPPORTED)
Func("do_unpack", {ret="void"; "pointer" --[[png_row_infop row_info]], "pointer" --[[png_bytep row]]})
-- #endif

-- #if defined(PNG_READ_SHIFT_SUPPORTED)
Func("do_unshift", {ret="void"; "pointer" --[[png_row_infop row_info]], "pointer" --[[png_bytep row]], "pointer" --[[png_color_8p sig_bits]]})
-- #endif

-- #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
Func("do_invert", {ret="void"; "pointer" --[[png_row_infop row_info]], "pointer" --[[png_bytep row]]})
-- #endif

-- #if defined(PNG_READ_16_TO_8_SUPPORTED)
Func("do_chop", {ret="void"; "pointer" --[[png_row_infop row_info]], "pointer" --[[png_bytep row]]})
-- #endif

-- #if defined(PNG_READ_DITHER_SUPPORTED)
Func("do_dither", {ret="void";
  "pointer" --[[png_row_infop row_info]],
  "pointer" --[[png_bytep row]],
  "pointer" --[[png_bytep palette_lookup]],
  "pointer" --[[png_bytep dither_lookup]]})

  -- #if defined(PNG_CORRECT_PALETTE_SUPPORTED)
  Func("correct_palette", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_colorp palette]], "int" --[[num_palette]]})
  -- #endif
  
-- #endif

-- #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
Func("do_bgr", {ret="void";
  "pointer" --[[png_row_infop row_info]],
  "pointer" --[[png_bytep row]]})
-- #endif

-- #if defined(PNG_WRITE_PACK_SUPPORTED)
Func("do_pack", {ret="void";
  "pointer" --[[png_row_infop row_info]],
  "pointer" --[[png_bytep row]],
  "uint" --[[bit_depth]]})
-- #endif

-- #if defined(PNG_WRITE_SHIFT_SUPPORTED)
Func("do_shift", {ret="void";
  "pointer" --[[png_row_infop row_info]],
  "pointer" --[[png_bytep row]],
  "pointer" --[[png_color_8p bit_depth]]})
-- #endif

-- #if defined(PNG_READ_BACKGROUND_SUPPORTED)
Func("do_background", {ret="void";
  "pointer" --[[png_row_infop row_info]],
  "pointer" --[[png_bytep row]],
  "pointer" --[[png_color_16p trans_values]],
  "pointer" --[[png_color_16p background]],
  "pointer" --[[png_color_16p background_1]],
  "pointer" --[[png_bytep gamma_table]],
  "pointer" --[[png_bytep gamma_from_1]],
  "pointer" --[[png_bytep gamma_to_1]],
  "pointer" --[[png_uint_16pp gamma_16]],
  "pointer" --[[png_uint_16pp gamma_16_from_1]],
  "pointer" --[[png_uint_16pp gamma_16_to_1]],
  "int" --[[gamma_shift]]})
-- #endif

-- #if defined(PNG_READ_GAMMA_SUPPORTED)
Func("do_gamma", {ret="void";
  "pointer" --[[png_row_infop row_info]],
  "pointer" --[[png_bytep row]],
  "pointer" --[[png_bytep gamma_table]],
  "pointer" --[[png_uint_16pp gamma_16_table]],
  "int" --[[gamma_shift]]})
-- #endif

-- #if defined(PNG_READ_EXPAND_SUPPORTED)
Func("do_expand_palette", {ret="void";
  "pointer" --[[png_row_infop row_info]],
  "pointer" --[[png_bytep row]],
  "pointer" --[[png_colorp palette]],
  "pointer" --[[png_bytep trans]],
  "int" --[[num_trans]]})
Func("do_expand", {ret="void"; "pointer" --[[png_row_infop row_info]], "pointer" --[[png_bytep row]], "pointer" --[[png_color_16p trans_value]]})
-- #endif

--[[ The following decodes the appropriate chunks, and does error correction,
 * then calls the appropriate callback for the chunk if it is valid.
 --]]

-- decode the IHDR chunk
Func("handle_IHDR", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_infop info_ptr]], "uint" --[[length]]})
Func("handle_PLTE", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_infop info_ptr]], "uint" --[[length]]})
Func("handle_IEND", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_infop info_ptr]], "uint" --[[length]]})

-- #if defined(PNG_READ_gAMA_SUPPORTED)
Func("handle_gAMA", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_infop info_ptr]], "uint" --[[length]]})
-- #endif

-- #if defined(PNG_READ_sBIT_SUPPORTED)
Func("handle_sBIT", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_infop info_ptr]], "uint" --[[length]]})
-- #endif

-- #if defined(PNG_READ_cHRM_SUPPORTED)
Func("handle_cHRM", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_infop info_ptr]], "uint" --[[length]]})
-- #endif

-- #if defined(PNG_READ_sRGB_SUPPORTED)
Func("handle_sRGB", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_infop info_ptr]], "uint" --[[length]]})
-- #endif

-- #if defined(PNG_READ_tRNS_SUPPORTED)
Func("handle_tRNS", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_infop info_ptr]], "uint" --[[length]]})
-- #endif

-- #if defined(PNG_READ_bKGD_SUPPORTED)
Func("handle_bKGD", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_infop info_ptr]], "uint" --[[length]]})
-- #endif

-- #if defined(PNG_READ_hIST_SUPPORTED)
Func("handle_hIST", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_infop info_ptr]], "uint" --[[length]]})
-- #endif

-- #if defined(PNG_READ_oFFs_SUPPORTED)
Func("handle_oFFs", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_infop info_ptr]], "uint" --[[length]]})
-- #endif

-- #if defined(PNG_READ_pCAL_SUPPORTED)
Func("handle_pCAL", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_infop info_ptr]],  "uint" --[[length]]})
-- #endif

-- #if defined(PNG_READ_pHYs_SUPPORTED)
Func("handle_pHYs", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_infop info_ptr]], "uint" --[[length]]})
-- #endif

-- #if defined(PNG_READ_tIME_SUPPORTED)
Func("handle_tIME", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_infop info_ptr]], "uint" --[[length]]})
-- #endif

-- #if defined(PNG_READ_tEXt_SUPPORTED)
Func("handle_tEXt", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_infop info_ptr]], "uint" --[[length]]})
-- #endif

-- #if defined(PNG_READ_zTXt_SUPPORTED)
Func("handle_zTXt", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_infop info_ptr]], "uint" --[[length]]})
-- #endif

Func("handle_unknown", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_infop info_ptr]], "uint" --[[length]]})

Func("check_chunk_name", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_bytep chunk_name]]})

-- handle the transformations for reading and writing
Func("do_read_transformations", {ret="void"; "pointer" --[[png_structp png_ptr]]})
Func("do_write_transformations", {ret="void"; "pointer" --[[png_structp png_ptr]]})

Func("init_read_transformations", {ret="void"; "pointer" --[[png_structp png_ptr]]})

-- #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
Func("push_read_chunk", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_infop info_ptr]]})
Func("push_read_sig", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_infop info_ptr]]})
Func("push_check_crc", {ret="void"; "pointer" --[[png_structp png_ptr]]})
Func("push_crc_skip", {ret="void"; "pointer" --[[png_structp png_ptr]], "uint" --[[length]]})
Func("push_crc_finish", {ret="void"; "pointer" --[[png_structp png_ptr]]})
Func("push_fill_buffer", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_bytep buffer]], png_size_t length})
Func("push_save_buffer", {ret="void"; "pointer" --[[png_structp png_ptr]]})
Func("push_restore_buffer", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_bytep buffer]], png_size_t buffer_length})
Func("push_read_IDAT", {ret="void"; "pointer" --[[png_structp png_ptr]]})
Func("process_IDAT_data", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_bytep buffer]], png_size_t buffer_length})
Func("push_process_row", {ret="void"; "pointer" --[[png_structp png_ptr]]})
Func("push_handle_unknown", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_infop info_ptr]], "uint" --[[length]]})
Func("push_have_info", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_infop info_ptr]]})
Func("push_have_end", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_infop info_ptr]]})
Func("push_have_row", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_bytep row]]})
Func("push_read_end", {ret="void"; "pointer" --[[png_structp png_ptr]],
   "pointer" --[[png_infop info_ptr]]})
Func("process_some_data", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_infop info_ptr]]})
Func("read_push_finish_row", {ret="void"; "pointer" --[[png_structp png_ptr]]})
-- #if defined(PNG_READ_tEXt_SUPPORTED)
Func("push_handle_tEXt", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_infop info_ptr]], "uint" --[[length]]})
Func("push_read_tEXt", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_infop info_ptr]]})
-- #endif
-- #if defined(PNG_READ_zTXt_SUPPORTED)
Func("push_handle_zTXt", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_infop info_ptr]], "uint" --[[length]]})
Func("push_read_zTXt", {ret="void"; "pointer" --[[png_structp png_ptr]], "pointer" --[[png_infop info_ptr]]})
-- #endif

--]=====]
